﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;

namespace SpaceshipDuel
{
    /// <summary>
    /// Explosionstypen
    /// </summary>
    enum ExplosionType
    {
        ship1Explosion = 1,
        ship2Explosion = 2,
        general = 3,
        ship1Warp = 4,
        ship2Warp = 5,
        atomShockwave = 6,
    }

    /// <summary>
    /// Klasse für Explosionen
    /// </summary>
    class Explosion : GameObject
    {
        #region Private fields

        WaitTimer animTimer;    // Timer für Animation der Explosion (schaltet Frames weiter)
        int currentFrame;       // Nummer des aktuellen Frames der Explosionsanimation
        int maxFrame;
        bool destroyMe;         // Selbstzerstörungsflag des Objekts
        ExplosionType type;     // Explosionstyp
        float rotationAngle;      // Rotationswinkel

        #endregion Private fields

        #region Public properties

        public bool DestroyMe
        {
            get { return this.destroyMe; }
            set { this.destroyMe = value; }
        }

        public ExplosionType Type
        {
            get { return this.type; }
            set { this.type = value; }
        }

        public bool Reverse { get; set; }

        #endregion Public properties

        #region Construction

        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="newTexture">Textur</param>
        /// <param name="newPosition">Position</param>
        /// <param name="newType">Explosionstyp</param>
        public Explosion(TextureData newTextureData, Vector2 newCenter, ExplosionType newType, float newRotationAngle = 0f, bool setReverse = false)
        {
            textureData = newTextureData;
            center = newCenter;
            type = newType;
            maxFrame = newTextureData.tileCountX * newTextureData.tileCountY;
            destroyMe = false;
            rotationAngle = newRotationAngle;
            Reverse = setReverse;

            if (!Reverse)
                currentFrame = 0;
            else
                currentFrame = textureData.tileCountX * textureData.tileCountY - 1;

            switch (newType)
            {
                case ExplosionType.ship1Warp:
                case ExplosionType.ship2Warp:
                    animTimer = new WaitTimer(0.005f);
                    break;
                case ExplosionType.atomShockwave:
                    animTimer = new WaitTimer(0.001f);
                    break;
                default:
                    animTimer = new WaitTimer(0.02f);
                    break;
            }
        }

        #endregion Construction

        #region Public methods

        /// <summary>
        /// Update-Methode für den Schuss
        /// </summary>
        public void Update(GameTime gameTime)
        {
            if (animTimer.IsElapsed(gameTime.ElapsedGameTime.TotalSeconds))
            {
                if (type == ExplosionType.atomShockwave)
                {
                    currentFrame=currentFrame+25; // zählt die Animationsframes = Durchmesser der Textur / Explosion

                    if (currentFrame >= 1000)
                    {
                        currentFrame = 1000;
                        destroyMe = true;
                    }
                }
                else
                {
                    if (!Reverse)
                    {
                        if (currentFrame < maxFrame)
                            currentFrame++;
                        else
                            destroyMe = true;
                    }
                    else
                    {
                        if (currentFrame > 0)
                            currentFrame--;
                        else
                            destroyMe = true;
                    }
                }
            }
        }

        /// <summary>
        /// Draw-Methode
        /// </summary>
        /// <param name="spriteBatch">Spritebatch</param>
        /// <param name="xOffset">Offset X</param>
        /// <param name="yOffset">Offset Y</param>
        new public void Draw(SpriteBatch spriteBatch, float xOffset, float yOffset)
        {
            if (destroyMe == false)
            {
                if (type == ExplosionType.atomShockwave)
                {
                    //Rectangle destRect = new Rectangle((int)center.X - currentFrame/2, (int)center.Y - currentFrame/2, currentFrame, currentFrame);
                    Rectangle destRect = new Rectangle((int)center.X, (int)center.Y, currentFrame, currentFrame);
                    Rectangle sourceRect = new Rectangle(0, 0, textureData.tileWidth, textureData.tileHeight);
                    Vector2 origin = new Vector2(textureData.tileWidth / 2, textureData.tileHeight / 2);
                    //Color expColor = Color.FromNonPremultiplied(255,255,255, (510 - Math.Max(currentFrame - 490, 0)) / 2);
                    Color expColor = Color.FromNonPremultiplied(255, 255, 255, (int)((1000 - currentFrame)/1000f * 128));
                    spriteBatch.Draw(textureData.texture, destRect, sourceRect, expColor, rotationAngle, origin, SpriteEffects.None, 0);
                }
                else
                {
                    Rectangle destRect = new Rectangle((int)center.X, (int)center.Y, textureData.tileWidth, textureData.tileHeight);
                    Rectangle sourceRect = new Rectangle(currentFrame % textureData.tileCountX * textureData.tileWidth, currentFrame / textureData.tileCountX * textureData.tileHeight, textureData.tileWidth, textureData.tileHeight);
                    Vector2 origin = new Vector2(textureData.tileWidth / 2, textureData.tileHeight / 2);
                    spriteBatch.Draw(textureData.texture, destRect, sourceRect, Color.White, rotationAngle, origin, SpriteEffects.None, 0);
                }
            }
        }

        #endregion Public methods
    }
}
